package com.fadadianqi.logistics.admin.net.mina;

import com.fadadianqi.logistics.admin.net.Packet;
import com.fadadianqi.logistics.admin.net.PacketHead;
import com.fadadianqi.logistics.admin.net.packet.PacketParser;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;

import java.nio.ByteBuffer;

/**
 * @author aroot
 */
public class Decoder extends CumulativeProtocolDecoder {

    private static final Log LOG = LogFactory.getLog(Decoder.class);

    /**
     *
     */
    @Override
    protected boolean doDecode(IoSession session, IoBuffer in,
                               ProtocolDecoderOutput out) throws Exception {
        /*if (LOG.isWarnEnabled()) {
			LOG.warn("#doDecode#, type:" + type + "; len:remaining, " + len + ":" + (in.remaining()));
		}*/
        LOG.debug("IoBuffer#remaining:" + in.remaining());
        if (in.remaining() > 0) {
            in.mark();
            int action = in.getInt();
            int bodyLen = in.getInt();
            LOG.debug("IoBuffer#action:" + action + ", bodyLen:" + bodyLen + ", remaining:" + in.remaining());
            if (bodyLen > in.remaining()) {
                in.reset();
                return false;
            } else {
                LOG.debug("IoBuffer#复制1个完整消息");
                // 复制1个完整消息
                ByteBuffer buf = ByteBuffer.allocate(PacketHead.LEN + bodyLen);
                buf.putInt(action);
                buf.putInt(bodyLen);
                if (bodyLen > 0) {
                    byte[] bytes = new byte[bodyLen];
                    in.get(bytes, 0, bodyLen);
                    buf.put(bytes);
                }
                buf.flip();
                Packet packet = PacketParser.parse(buf.array());
                out.write(packet);
                if (in.remaining() > 0) {
                    return true;
                }
            }
        }
        return false;
    }
}
